package com.antaohua.platfrom.framework.base.dao;

import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaDelete;
import javax.persistence.criteria.CriteriaBuilder.In;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.CriteriaUpdate;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

//import org.apache.commons.logging.Log;
//import org.apache.commons.logging.LogFactory;

import com.antaohua.platfrom.framework.base.utils.Condition;
import com.antaohua.platfrom.framework.base.utils.PageUtil;
import com.antaohua.platfrom.framework.base.interfase.BaseDao;
import com.antaohua.platfrom.framework.base.interfase.DeleteStateInterfase;
import com.antaohua.platfrom.framework.base.interfase.UpdateDateInterfase;
import com.antaohua.platfrom.framework.base.model.UUIDIdentityModel;
import com.antaohua.platfrom.framework.container.ThreeColumn;
import com.antaohua.platfrom.framework.container.ThreeEntry;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

public abstract class BaseJpaDao<E extends UUIDIdentityModel> implements BaseDao<E>{

	//private final static Log log = LogFactory.getLog(BaseJpaDao.class);
	
	protected abstract Class<E> getEntityClass();
	
	
	@PersistenceContext
    private EntityManager entityManager;
	
	private CriteriaBuilder criteriaBuilder;
	
	
	
	
	
	
	
	protected EntityManager getEntityManager() {
		return entityManager;
	}
	
	protected CriteriaBuilder getCriteriaBuilder() {
		if(criteriaBuilder==null) {
			this.criteriaBuilder = entityManager.getCriteriaBuilder();
		}
		return this.criteriaBuilder;
	}
	
	

	

	public Query getQuery(String queryString) {
		return entityManager.createQuery(queryString);
	}
	
	public TypedQuery<E> getQuery(String queryString, Class<E> resultType) {
		return entityManager.createQuery(queryString, resultType);
	}
	
	
	
	

	
	public E findById(String id) {
		return entityManager.find(getEntityClass(), id);
	}
	
	public E save(E entity) {
		entity = BaseHibernateManager.createEventAutoData(entity);
		this.entityManager.persist(entity);
		return entity;
	}
	
	public List<E> save(List<E> entitys) {
		for (int i = 0; i < entitys.size(); i++) {
			save(entitys.get(i));
		}
		return entitys;
		
	}
	
	public E update(E entity) {
		entity = BaseHibernateManager.updateEventAutoData(entity);
		return this.entityManager.merge(entity);
	}
	
	public int updateById(String updateProperty,Object updateData,String id) {
		
		CriteriaUpdate<E> update = getCriteriaBuilder().createCriteriaUpdate(getEntityClass());
		Root<E> root = update.from(getEntityClass());
		List<Predicate> where = Lists.newArrayList();
		where.add(getCriteriaBuilder().equal(root.get("id"),id));
		update.set(updateProperty, updateData);
		if(BaseHibernateManager.isUpdateDate(getEntityClass())) {
			update.set(UpdateDateInterfase.UPDAT_ATTRIBUTE_NAME, new Date());
		}
		update.where(where.toArray(new Predicate[0]));
		return entityManager.createQuery(update).executeUpdate();
	}
	
	
	public int updateByIds(String updateProperty,Object updateData,String[] ids) {
		
		CriteriaUpdate<E> update = getCriteriaBuilder().createCriteriaUpdate(getEntityClass());
		Root<E> root = update.from(getEntityClass());
		
		update.set(updateProperty, updateData);
		List<Predicate> where = Lists.newArrayList();
		In<String> in = getCriteriaBuilder().in(root.get("id"));
		for (String id : ids) {
			in.value(id);
		}
		where.add(in);
		if(BaseHibernateManager.isUpdateDate(getEntityClass())) {
			update.set(UpdateDateInterfase.UPDAT_ATTRIBUTE_NAME, new Date());
		}
		update.where(where.toArray(new Predicate[0]));
		return entityManager.createQuery(update).executeUpdate();
	}
	
	
	public int updateByProperty(String updateProperty,Object updateData,String whereProperty,Object whereData) {
		
		CriteriaUpdate<E> update = getCriteriaBuilder().createCriteriaUpdate(getEntityClass());
		Root<E> root = update.from(getEntityClass());
		
		List<Predicate> where = Lists.newArrayList();
		where.add(getCriteriaBuilder().equal(root.get(whereProperty),whereData));
		update.set(updateProperty, updateData);
		if(BaseHibernateManager.isUpdateDate(getEntityClass())) {
			update.set(UpdateDateInterfase.UPDAT_ATTRIBUTE_NAME, new Date());
		}
		update.where(where.toArray(new Predicate[0]));
		return entityManager.createQuery(update).executeUpdate();
	}
	
	public int updateByPropertys(Map<String, Object> updateData,ThreeColumn<String, Condition, Object> wherePropertys) {
		CriteriaUpdate<E> update = getCriteriaBuilder().createCriteriaUpdate(getEntityClass());
		Root<E> root = update.from(getEntityClass());
		
		List<Predicate> where = Lists.newArrayList();
		for (ThreeEntry<String, Condition, Object> entry : wherePropertys.entrySet()) {
			where.add(entry.getCharacter().getJpaCriterion(getCriteriaBuilder(), root, entry.getKey(), entry.getValue()));
		}
		for (Map.Entry<String, Object> data : updateData.entrySet()) {
			update.set(data.getKey(), data.getValue());
		}
		if(BaseHibernateManager.isUpdateDate(getEntityClass())) {
			update.set(UpdateDateInterfase.UPDAT_ATTRIBUTE_NAME, new Date());
		}
		update.where(where.toArray(new Predicate[0]));
		return entityManager.createQuery(update).executeUpdate();
	}
	
	
	public void delete(E entity) {
		this.entityManager.remove(entity);
	}
	public int deleteById(String id) {
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			return updateById(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME, DeleteStateInterfase.DELETE_TRUE, id);
		}else {
			CriteriaDelete<E> delete = getCriteriaBuilder().createCriteriaDelete(getEntityClass());
			Root<E> root = delete.from(getEntityClass());
			delete.where(getCriteriaBuilder().equal(root.get("id"),id));
			return entityManager.createQuery(delete).executeUpdate();
		}
		
	}
	
	public int deleteByIds(String[] ids) {
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			return updateByIds(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME, DeleteStateInterfase.DELETE_TRUE, ids);
		}else {
			CriteriaDelete<E> delete = getCriteriaBuilder().createCriteriaDelete(getEntityClass());
			Root<E> root = delete.from(getEntityClass());
			In<String> in = getCriteriaBuilder().in(root.get("id"));
			for (String id : ids) {
				in.value(id);
			}
			delete.where();
			return entityManager.createQuery(delete).executeUpdate();
		}
		
	}
	
	
	public int deleteByProperty(String whereProperty,Object whereData) {
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			return updateByProperty(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME, DeleteStateInterfase.DELETE_TRUE, whereProperty, whereData);
		}
		CriteriaDelete<E> delete = getCriteriaBuilder().createCriteriaDelete(getEntityClass());
		Root<E> root = delete.from(getEntityClass());

		delete.where(getCriteriaBuilder().equal(root.get(whereProperty),whereData));
		return entityManager.createQuery(delete).executeUpdate();
	}
	
	public int deleteByPropertys(ThreeColumn<String, Condition, Object> wherePropertys) {
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			Map<String, Object> updateData = Maps.newHashMap();
			updateData.put(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME, DeleteStateInterfase.DELETE_TRUE);
			return updateByPropertys(updateData, wherePropertys);
		}
		CriteriaDelete<E> delete = getCriteriaBuilder().createCriteriaDelete(getEntityClass());
		Root<E> root = delete.from(getEntityClass());
		
		List<Predicate> where = Lists.newArrayList();
		for (ThreeEntry<String, Condition, Object> entry : wherePropertys.entrySet()) {
			where.add(entry.getCharacter().getJpaCriterion(getCriteriaBuilder(), root, entry.getKey(), entry.getValue()));
		}
		delete.where(where.toArray(new Predicate[0]));
		return entityManager.createQuery(delete).executeUpdate();
	}
	
	
	
	
	public List<E> findByIds(List<String> ids){
		CriteriaQuery<E> query = getCriteriaBuilder().createQuery(getEntityClass());
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(entityRoot);
		In<String> in = getCriteriaBuilder().in(entityRoot.get("id"));
		for (String id : ids) {
			in.value(id);
		}
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			query.where(in,getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}else {
			query.where(in);
		}
		return this.entityManager.createQuery(query).getResultList();
	}
	
	
	public List<E> findByIds(String [] ids){
		CriteriaQuery<E> query = getCriteriaBuilder().createQuery(getEntityClass());
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(entityRoot);
		In<String> in = getCriteriaBuilder().in(entityRoot.get("id"));
		for (String id : ids) {
			in.value(id);
		}
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			query.where(in,getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}else {
			query.where(in);
		}
		
		return this.entityManager.createQuery(query).getResultList();
	}
	
	public List<E> findAll(){
		CriteriaQuery<E> query = getCriteriaBuilder().createQuery(getEntityClass());
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(entityRoot);
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			query.where(getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}
		return this.entityManager.createQuery(query).getResultList();
	}
	
	public List<E> findAllOrder(String orderProperty , Boolean asc){
		CriteriaQuery<E> query = getCriteriaBuilder().createQuery(getEntityClass());
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(entityRoot);
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			query.where(getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}
		List<Order> orderBy = Lists.newArrayList();
		if(asc) {
			orderBy.add(getCriteriaBuilder().asc(entityRoot.get(orderProperty)));
		}else {
			orderBy.add(getCriteriaBuilder().desc(entityRoot.get(orderProperty)));
		}
		query.orderBy(orderBy.toArray(new Order[0]));
		return this.entityManager.createQuery(query).getResultList();
	}
	
	public PageUtil<E> findAllFotPage(PageUtil<E> page){
		CriteriaQuery<E> query = getCriteriaBuilder().createQuery(getEntityClass());
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(entityRoot);
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			query.where(getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}
		page.setTotal(count());
		page.setRoot(this.entityManager.createQuery(query).setFirstResult(page.getFirstNumber()).setMaxResults(page.getLastNumber()).getResultList());
		return page;
	}
	
	public PageUtil<E> findAllPageOrder(PageUtil<E> page,String orderProperty , Boolean asc){
		CriteriaQuery<E> query = getCriteriaBuilder().createQuery(getEntityClass());
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(entityRoot);
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			query.where(getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}
		List<Order> orderBy = Lists.newArrayList();
		if(asc) {
			orderBy.add(getCriteriaBuilder().asc(entityRoot.get(orderProperty)));
		}else {
			orderBy.add(getCriteriaBuilder().desc(entityRoot.get(orderProperty)));
		}
		query.orderBy(orderBy.toArray(new Order[0]));
		page.setTotal(count());
		page.setRoot(this.entityManager.createQuery(query).setFirstResult(page.getFirstNumber()).setMaxResults(page.getLastNumber()).getResultList());
		return page;
	}
	
	public List<E> findByProperty(String whereProperty,Object whereData){
		CriteriaQuery<E> query = getCriteriaBuilder().createQuery(getEntityClass());
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(entityRoot);
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			query.where(getCriteriaBuilder().equal(entityRoot.get(whereProperty), whereData),getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}else {
			query.where(getCriteriaBuilder().equal(entityRoot.get(whereProperty), whereData));
		}
		
		return this.entityManager.createQuery(query).getResultList();
	}
	public List<E> findByProperty(ThreeEntry<String, Condition, Object> whereProperty){
		CriteriaQuery<E> query = getCriteriaBuilder().createQuery(getEntityClass());
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(entityRoot);
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			query.where(whereProperty.getCharacter().getJpaCriterion(getCriteriaBuilder(), entityRoot, whereProperty.getKey(), whereProperty.getValue()),getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}else {
			query.where(whereProperty.getCharacter().getJpaCriterion(getCriteriaBuilder(), entityRoot, whereProperty.getKey(), whereProperty.getValue()));
		}
		return this.entityManager.createQuery(query).getResultList();
	}
	
	
	public List<E> findByPropertys(ThreeColumn<String, Condition, Object> wherePropertys){
		CriteriaQuery<E> query = getCriteriaBuilder().createQuery(getEntityClass());
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(entityRoot);
		List<Predicate> where = Lists.newArrayList();
		for (ThreeEntry<String, Condition, Object> entry : wherePropertys.entrySet()) {
			where.add(entry.getCharacter().getJpaCriterion(getCriteriaBuilder(), entityRoot, entry.getKey(), entry.getValue()));
		}
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			where.add(getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}
		
		query.where(where.toArray(new Predicate[0]));
		return this.entityManager.createQuery(query).getResultList();
	}
	
	public List<E> findByPropertys(Map<String, Object> wherePropertys){
		CriteriaQuery<E> query = getCriteriaBuilder().createQuery(getEntityClass());
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(entityRoot);
		List<Predicate> where = Lists.newArrayList();
		for (Map.Entry<String,Object> entry : wherePropertys.entrySet()) {
			where.add(getCriteriaBuilder().equal(entityRoot.get(entry.getKey()), entry.getValue()));
		}
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			where.add(getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}
		query.where(where.toArray(new Predicate[0]));
		return this.entityManager.createQuery(query).getResultList();
	}
	
	public List<E> findByPropertyOrder(String whereProperty,Object whereData,String orderProperty , Boolean asc){
		CriteriaQuery<E> query = getCriteriaBuilder().createQuery(getEntityClass());
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(entityRoot);
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			query.where(getCriteriaBuilder().equal(entityRoot.get(whereProperty), whereData),getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}else {
			query.where(getCriteriaBuilder().equal(entityRoot.get(whereProperty), whereData));
		}
		List<Order> orderBy = Lists.newArrayList();
		if(asc) {
			orderBy.add(getCriteriaBuilder().asc(entityRoot.get(orderProperty)));
		}else {
			orderBy.add(getCriteriaBuilder().desc(entityRoot.get(orderProperty)));
		}
		query.orderBy(orderBy.toArray(new Order[0]));
		return this.entityManager.createQuery(query).getResultList();
	}
	
	
	public List<E> findByPropertysOrder(ThreeColumn<String, Condition, Object> wherePropertys,Map<String, Boolean> orders){
		CriteriaQuery<E> query = getCriteriaBuilder().createQuery(getEntityClass());
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(entityRoot);
		List<Predicate> where = Lists.newArrayList();
		for (ThreeEntry<String, Condition, Object> entry : wherePropertys.entrySet()) {
			where.add(entry.getCharacter().getJpaCriterion(getCriteriaBuilder(), entityRoot, entry.getKey(), entry.getValue()));
		}
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			where.add(getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}
		query.where(where.toArray(new Predicate[0]));
		List<Order> orderBy = Lists.newArrayList();
		for (Map.Entry<String, Boolean> order : orders.entrySet()) {
			if(order.getValue()) {
				orderBy.add(getCriteriaBuilder().asc(entityRoot.get(order.getKey())));
			}else {
				orderBy.add(getCriteriaBuilder().desc(entityRoot.get(order.getKey())));
			}
		}
		query.orderBy(orderBy.toArray(new Order[0]));
		return this.entityManager.createQuery(query).getResultList();
	}
	
	
	
	
	
	public PageUtil<E> findPageByPropertyOrder(PageUtil<E> page,String whereProperty,Object whereData,String orderProperty , Boolean asc){
		CriteriaQuery<E> query = getCriteriaBuilder().createQuery(getEntityClass());
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(entityRoot);
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			query.where(getCriteriaBuilder().equal(entityRoot.get(whereProperty), whereData),getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}else {
			query.where(getCriteriaBuilder().equal(entityRoot.get(whereProperty), whereData));
		}
		
		List<Order> orderBy = Lists.newArrayList();
		if(asc) {
			orderBy.add(getCriteriaBuilder().asc(entityRoot.get(orderProperty)));
		}else {
			orderBy.add(getCriteriaBuilder().desc(entityRoot.get(orderProperty)));
		}
		query.orderBy(orderBy.toArray(new Order[0]));
		page.setTotal(countByProperty(whereProperty,whereData));
		page.setRoot(this.entityManager.createQuery(query).setFirstResult(page.getFirstNumber()).setMaxResults(page.getLastNumber()).getResultList());
		return page;
	}
	
	public PageUtil<E> findPageByPropertyOrder(PageUtil<E> page,ThreeEntry<String, Condition, Object> whereProperty,String orderProperty , Boolean asc){
		CriteriaQuery<E> query = getCriteriaBuilder().createQuery(getEntityClass());
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(entityRoot);
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			query.where(whereProperty.getCharacter().getJpaCriterion(getCriteriaBuilder(), entityRoot, whereProperty.getKey(), whereProperty.getValue()),getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}else {
			query.where(whereProperty.getCharacter().getJpaCriterion(getCriteriaBuilder(), entityRoot, whereProperty.getKey(), whereProperty.getValue()));
		}
		
		List<Order> orderBy = Lists.newArrayList();
		if(asc) {
			orderBy.add(getCriteriaBuilder().asc(entityRoot.get(orderProperty)));
		}else {
			orderBy.add(getCriteriaBuilder().desc(entityRoot.get(orderProperty)));
		}
		query.orderBy(orderBy.toArray(new Order[0]));
		page.setTotal(countByProperty(whereProperty));
		page.setRoot(this.entityManager.createQuery(query).setFirstResult(page.getFirstNumber()).setMaxResults(page.getLastNumber()).getResultList());
		return page;
	}
	
	public PageUtil<E> findPageByPropertysOrder(PageUtil<E> page,ThreeColumn<String, Condition, Object> wherePropertys,String orderProperty , Boolean asc){
		CriteriaQuery<E> query = getCriteriaBuilder().createQuery(getEntityClass());
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(entityRoot);
		List<Predicate> where = Lists.newArrayList();
		for (ThreeEntry<String, Condition, Object> entry : wherePropertys.entrySet()) {
			where.add(entry.getCharacter().getJpaCriterion(getCriteriaBuilder(), entityRoot, entry.getKey(), entry.getValue()));
		}
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			where.add(getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}
		
		query.where(where.toArray(new Predicate[0]));
		List<Order> orderBy = Lists.newArrayList();
		if(asc) {
			orderBy.add(getCriteriaBuilder().asc(entityRoot.get(orderProperty)));
		}else {
			orderBy.add(getCriteriaBuilder().desc(entityRoot.get(orderProperty)));
		}
		query.orderBy(orderBy.toArray(new Order[0]));
		page.setTotal(countByPropertys(wherePropertys));
		page.setRoot(this.entityManager.createQuery(query).setFirstResult(page.getFirstNumber()).setMaxResults(page.getLastNumber()).getResultList());
		return page;
	}
	
	public PageUtil<E> findPageByPropertysOrder(PageUtil<E> page,ThreeColumn<String, Condition, Object> wherePropertys,Map<String, Boolean> orders){
		CriteriaQuery<E> query = getCriteriaBuilder().createQuery(getEntityClass());
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(entityRoot);
		List<Predicate> where = Lists.newArrayList();
		for (ThreeEntry<String, Condition, Object> entry : wherePropertys.entrySet()) {
			where.add(entry.getCharacter().getJpaCriterion(getCriteriaBuilder(), entityRoot, entry.getKey(), entry.getValue()));
		}
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			where.add(getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}
		query.where(where.toArray(new Predicate[0]));
		List<Order> orderBy = Lists.newArrayList();
		for (Map.Entry<String, Boolean> order : orders.entrySet()) {
			if(order.getValue()) {
				orderBy.add(getCriteriaBuilder().asc(entityRoot.get(order.getKey())));
			}else {
				orderBy.add(getCriteriaBuilder().desc(entityRoot.get(order.getKey())));
			}
		}
		query.orderBy(orderBy.toArray(new Order[0]));
		page.setTotal(countByPropertys(wherePropertys));
		page.setRoot(this.entityManager.createQuery(query).setFirstResult(page.getFirstNumber()).setMaxResults(page.getLastNumber()).getResultList());
		return page;
	}
	
	public Long countByPropertys(ThreeColumn<String, Condition, Object> wherePropertys){
		CriteriaQuery<Long> query = getCriteriaBuilder().createQuery(Long.class);
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(getCriteriaBuilder().count(entityRoot));
		List<Predicate> where = Lists.newArrayList();
		for (ThreeEntry<String, Condition, Object> entry : wherePropertys.entrySet()) {
			where.add(entry.getCharacter().getJpaCriterion(getCriteriaBuilder(), entityRoot, entry.getKey(), entry.getValue()));
		}
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			where.add(getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}
		query.where(where.toArray(new Predicate[0]));
		return this.entityManager.createQuery(query).getSingleResult();
	}
	
	public Long countByProperty(ThreeEntry<String, Condition, Object> whereProperty){
		CriteriaQuery<Long> query = getCriteriaBuilder().createQuery(Long.class);
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(getCriteriaBuilder().count(entityRoot));
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			query.where(whereProperty.getCharacter().getJpaCriterion(getCriteriaBuilder(), entityRoot, whereProperty.getKey(), whereProperty.getValue()),getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));

		}else {
			query.where(whereProperty.getCharacter().getJpaCriterion(getCriteriaBuilder(), entityRoot, whereProperty.getKey(), whereProperty.getValue()));

		}
		return this.entityManager.createQuery(query).getSingleResult();
	}
	
	public Long countByProperty(String whereProperty,Object whereData){
		CriteriaQuery<Long> query = getCriteriaBuilder().createQuery(Long.class);
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(getCriteriaBuilder().count(entityRoot));
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			query.where(getCriteriaBuilder().equal(entityRoot.get(whereProperty), whereData),getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}else {
			query.where(getCriteriaBuilder().equal(entityRoot.get(whereProperty), whereData));
		}
		
		return this.entityManager.createQuery(query).getSingleResult();
	}
	
	public Long count(){
		CriteriaQuery<Long> query = getCriteriaBuilder().createQuery(Long.class);
		Root<E> entityRoot = query.from(getEntityClass());
		query.select(getCriteriaBuilder().count(entityRoot));
		if(BaseHibernateManager.isDeleteState(getEntityClass())) {
			query.where(getCriteriaBuilder().equal(entityRoot.get(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME), DeleteStateInterfase.DELETE_FALSE));
		}
		return this.entityManager.createQuery(query).getSingleResult();
	}
	
	
	
}
